package com.yanqingshan.platform.module.sys.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yanqingshan.platform.common.core.convert.BasePageListConvert;
import com.yanqingshan.platform.common.core.domain.BasePageList;
import com.yanqingshan.platform.common.core.domain.PageQuery;
import com.yanqingshan.platform.common.core.domain.R;
import com.yanqingshan.platform.common.utils.UserPasswordUtil;
import com.yanqingshan.platform.module.auth.model.domain.UserTokenInfo;
import com.yanqingshan.platform.module.auth.model.dto.AuthLoginReqVO;
import com.yanqingshan.platform.module.sys.convert.SysUserConvert;
import com.yanqingshan.platform.module.sys.mapper.SysUserMapper;
import com.yanqingshan.platform.module.sys.model.domain.SysRole;
import com.yanqingshan.platform.module.sys.model.domain.SysUser;
import com.yanqingshan.platform.module.sys.model.vo.ChangePasswordReqVO;
import com.yanqingshan.platform.module.sys.model.vo.SysUserDetailsRespVO;
import com.yanqingshan.platform.module.sys.model.vo.SysUserReqVO;
import com.yanqingshan.platform.module.sys.model.vo.SysUserRespVO;
import com.yanqingshan.platform.module.sys.service.SysRoleService;
import com.yanqingshan.platform.module.sys.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 功能描述: 系统用户 Service业务层处理
 *
 * @author yanqs
 * @since 2023-05-12
 */
@Slf4j
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Resource
    private SysRoleService roleService;

    /**
     * 创建系统用户
     *
     * @param param 请求参数
     * @return R
     */
    @Override
    public R createUser(SysUserReqVO param) {
        SysUser data = BeanUtil.copyProperties(param, SysUser.class);
        // 判断账户是否唯一
        if (!verifyUnique(data.getUserName())) {
            return R.failed("该账号已存在！");
        }
        log.debug("用户：{};原始密码：{}", param.getUserName(), param.getPassword());
        // 密码进行加密
        data.setPassword(UserPasswordUtil.passwordGenerated(data.getUserName(), param.getPassword()));
        log.debug("加密后：{}", data.getPassword());
        return R.status(this.save(data));
    }

    /**
     * 更新系统用户信息
     *
     * @param param 请求参数
     * @return R
     */
    @Override
    public R updateUser(SysUserReqVO param) {
        SysUser user = this.getById(param.getId());
        if (Objects.isNull(user)) {
            return R.failed("用户不存在！");
        }
        SysUser sysUser = SysUserConvert.INSTANCE.infoConvert(param);
        return R.status(this.updateById(sysUser));
    }

    /**
     * 修改密码
     *
     * @param param 请求参数
     * @return R
     */
    @Override
    public R changePassword(ChangePasswordReqVO param) {
        //获取当前登录用户的用户ID
        if (Objects.isNull(StpUtil.getLoginIdDefaultNull())) {
            return R.failed("当前用户未登录");
        }
        Long userId = StpUtil.getLoginIdAsLong();
        SysUser user = this.getById(userId);
        String currentPassword = UserPasswordUtil.passwordGenerated(user.getUserName(), param.getCurrentPassword());
        log.info("用户：{};原始密码：{};加密后密码：{};当前用户密码：{}",
                user.getUserName(), param.getCurrentPassword(), currentPassword, user.getPassword());
        if (currentPassword.equals(user.getPassword())) {
            String newPassword = UserPasswordUtil.passwordGenerated(user.getUserName(), param.getNewPassword());
            user.setPassword(newPassword);
            return R.status(this.updateById(user));
        }
        return R.failed("当前用户密码错误");
    }

    /**
     * 系统用户登录
     *
     * @param param 请求参数
     * @return R
     */
    @Override
    public R<UserTokenInfo> login(AuthLoginReqVO param) {
        UserTokenInfo result = new UserTokenInfo();
        SysUser user = getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, param.getUsername()));
        if (Objects.isNull(user)) {
            return R.failed("用户不存在");
        }
        String loginPassword = UserPasswordUtil.passwordGenerated(param.getUsername(), param.getPassword());
        if (loginPassword.equals(user.getPassword())) {
            StpUtil.login(user.getId());
            //获取当前用户的token信息、角色组、权限列表
            result.setToken(StpUtil.getTokenInfo());
            UserTokenInfo.UserInfo userInfo = SysUserConvert.INSTANCE.convert1(user);
            userInfo.setDashboard("1");
            // 查询角色列表
            List<String> roleList = roleService.listAliasByUser(user.getId());
            userInfo.setRole(roleList);
            //
            result.setUserInfo(userInfo);
            //List<String> permissionList = StpUtil.getPermissionList();
            //List<String> roleList = StpUtil.getRoleList();
            //result.setPermissionList(permissionList);
            //result.setRoleList(roleList);
            return R.ok(result);
        }
        return R.failed("密码错误");
    }

    /**
     * 删除用户
     *
     * @param id 用户id
     * @return R
     */
    @Override
    public R delUser(Long id) {
        SysUser user = this.getById(id);
        if (Objects.isNull(user)) {
            return R.failed("用户不存在");
        }
        return R.status(this.removeById(id));
    }

    /**
     * 分页查询用户
     *
     * @param param 查询参数
     * @param query 分页参数
     * @return
     */
    @Override
    public BasePageList<SysUserRespVO> pageCustom(SysUserReqVO param, PageQuery query) {
        Page<SysUser> resultPage = new Page(query.getPage(), query.getPageSize());
        LambdaQueryWrapper<SysUser> queryWrapper = createQuery(param);
        resultPage = page(resultPage, queryWrapper);
        Page<SysUserRespVO> result = SysUserConvert.INSTANCE.convert2(resultPage);
        return BasePageListConvert.INSTANCE.convert(result);
    }

    /**
     * 根据用户id获取详情
     *
     * @param id 用户id
     * @return 用户信息
     */
    @Override
    public SysUserDetailsRespVO getUserDetails(Long id) {
        SysUserDetailsRespVO user = new SysUserDetailsRespVO();
        SysUser userEntity = this.getById(id);
        BeanUtil.copyProperties(userEntity, user);
        List<SysRole> roleEntities = roleService.listRolesByUserId(id);
        List<String> roleNames = roleEntities.stream().map(SysRole::getRoleName).collect(Collectors.toList());
        user.setRoleNames(roleNames);
        return user;
    }

    private LambdaQueryWrapper<SysUser> createQuery(SysUserReqVO param) {
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();

        return queryWrapper;
    }


    /**
     * 验证账户是否唯一
     *
     * @return boolean
     */
    private boolean verifyUnique(String userName) {
        List<SysUser> userList = list(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName));
        if (Objects.nonNull(userList) && userList.size() > 0) {
            return false;
        }
        return true;
    }

    @Override
    public Long validateUserName(String userName, Long userId) {
        long result = this.baseMapper.selectCount(Wrappers.lambdaQuery(SysUser.class).eq(SysUser::getUserName, userName));
        if (Objects.nonNull(userId)) {
            SysUser user = this.getById(userId);
            if (StrUtil.equalsIgnoreCase(userName, user.getUserName())) {
                return 0L;
            }
        }
        return result;
    }

    /**
     * 查询用户待分配角色
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<SysRole> queryGrantRolesByUserId(Long userId) {
        Assert.notNull(userId, "用户编号不能为空");
        List<SysRole> roleEntities = Lists.newArrayList();
        List<SysRole> allRoles = roleService.list(Wrappers.emptyWrapper());
        List<SysRole> grantedRoles = this.queryRolesByUserId(userId);
        return CollUtil.subtractToList(allRoles, grantedRoles);
    }

    /**
     * 查询用户分配角色
     *
     * @param userId 用户id
     * @return
     */
    @Override
    public List<SysRole> queryRolesByUserId(Long userId) {
        List<SysRole> roleEntities = roleService.listRolesByUserId(userId);
        return roleEntities;
    }

    /**
     * 批量重置密码
     *
     * @param userIds  用户ID
     * @param password 密码
     * @return
     */
    @Override
    public boolean resetPassword(List<Long> userIds, String password) {
        List<SysUser> userList = list(new LambdaQueryWrapper<SysUser>().in(SysUser::getId, userIds));
        for (SysUser user : userList) {
            String newPassword = UserPasswordUtil.passwordGenerated(user.getUserName(), password);
            user.setPassword(newPassword);
        }
        return updateBatchById(userList);
    }
}
